<template>
	<a-spin class="inline-flex" :spinning="isUpload">
		<a-upload
			style="display: flex;"
			:list-type="isSingleMore?'picture-card':'text'"
			:fileList="fileList"
			:accept="`.${fileTypes.join(',.')}`"
			:before-upload="beforeUpload"
			:show-upload-list="false"
			:disabled="isUpload"
			v-bind="options"
			 :multiple="true"
			  @change="handleChange"
		>
			<slot/>
		</a-upload>
	</a-spin>
</template>
<script>
	import axios from 'axios'
	 import { debounce } from 'lodash'
import { getOSSToken,getSignUrl } from '@/api/common'
import OSS from 'ali-oss'

function getSuffix(filename) {
  const pos = filename.lastIndexOf('.')
  let suffix = ''
  if (pos !== -1) {
    suffix = filename.substring(pos)
  }
  return suffix
}

function randomString(len) {
  const date = new Date()
  len = len || 20
  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  var maxPos = chars.length
  var pwd = ''
  Array.from({ length: len }).forEach(() => {
    pwd += chars.charAt(Math.floor(Math.random() * maxPos))
  })
  return `${pwd}${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}${date.getHours()}${date.getMinutes()}${date.getSeconds()}`
}

function getContentType(suffix) {
  if (suffix === '.bmp') {
    return 'image/bmp'
  }
  if (suffix === '.gif') {
    return 'image/gif'
  }
  if (suffix === '.jpeg' ||
    suffix === '.jpg' ||
    suffix === '.png') {
    return 'image/jpg'
  }
  if (suffix === '.html') {
    return 'text/html'
  }
  if (suffix === '.txt') {
    return 'text/plain'
  }
  if (suffix === '.vsd') {
    return 'application/vnd.visio'
  }
  if (suffix === '.pptx' ||
    suffix === '.ppt') {
    return 'application/vnd.ms-powerpoint'
  }
  if (suffix === '.docx' ||
    suffix === '.doc') {
    return 'application/msword'
  }
  if (suffix === '.xml') {
    return 'text/xml'
  }
  return undefined
}

export default {
  name: 'Upload',
  props: {
    isSingleMore: {
      type: Boolean,
      default: false
    },
    fileSize: {
      type: Number,
      default: 3
    },
    parallel: {
      type: Number,
      default: 3
    },
    partSize: {
      type: Number,
      default: 4
    },
    thumbnailPathWidth: { // 缩略图宽度
      type: Number,
      default: 100
    },
    thumbnailPathMode: { // 缩略图缩放模式
      type: String,
      default: 'fit'
    },
    fileTypes: {
      type: Array,
      default: () => ['png', 'jpeg', 'gif', 'jpg', 'webp']
    },
    //会员类型1
    scene: {
      type: Number,
      default: 3
    },
    options: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      isUpload: false,
      timer: null,
      seconds: 0,
      bucketDomain: '',
      filePath: '',
      ossClient: null,
      fileList: [],
      previewVisible: false,
      previewImage: '',
	    isHandlingFiles: false,
		isUploading:false,
		  hasUploaded: false, // 添加一个标志变量来控制是否已经上传过
		 
    }
  },
  created() {
  },
  methods: {
    beforeUpload(file, fileList) {
      const fileSize = this.fileSize
      if (file.size > 1024 * 1024 * fileSize) {
        this.$message.error(`不支持上传大于${fileSize}M的文件`)
        this.isUpload = false
        this.fileList = []
        return false
      }
      const fileTypes = this.fileTypes
      const fileTypesReg = new RegExp(`.(${this.fileTypes.join('|')})$`, 'i')
      if (!fileTypesReg.test(file.name)) {
        this.$message.error(`只能上传${fileTypes.join(',')}格式的文件`)
        this.isUpload = false
        this.fileList = []
        return false
      }
      this.fileList = fileList
     this.debounceUpload(fileList);
      return false
    },

   debounceUpload: debounce(function(file) {
	   let list=file.map(item => item.name);
	   
      this.upload(list,file);
	  
    }, 800), // 这里的 300 是防抖的延迟时间，你可以根据实际情况调整
    upload(file,files) {
		let obj={
			fileNames:file
		}
          getSignUrl(obj)
 	.then((data) => {
 	    data.items.forEach((item, index) => {  
 	        this.getUpload(item, files[index]);  
 	    });
 	})
 	.finally(() => (this.isUpload = false))
	  
    },

	async getUpload(item,files) {
	   const suffix = getSuffix(files.name)
	  try {
	    const formData = new FormData();
	   formData.append('key', item.dir);
	   formData.append('policy', item.policy);
	   formData.append('OSSAccessKeyId', item.ossAccessKeyId);
	   formData.append('signature', item.signature);
	   formData.append('success_action_status', '200');
	    formData.append('file', files);
	
	    // 发送 POST 请求来上传文件
	    const response = await axios.post(item.uploadUrl, formData, {
	      headers: {
	      'Content-Type': 'multipart/form-data'
	      }
	    });
	    // 文件上传成功后的处理逻辑
		this.$emit('uploadSuccess', {
		  name: files.name,
		  suffix,
		  path: item.fileUrl,
		  thumbnailPath: item.fileUrl
		})
	    console.log('File uploaded successfully:', response.data);
	  } catch (error) {
	    // 文件上传失败后的处理逻辑
	    console.error('Error uploading file:', error);
	  } finally {
	    this.isUpload = false; // 无论成功或失败，都在最终执行块中重置 isUpload 标志
	  }
	},
  //   upload(file) {
  //     // const { fileList: [file] } = this
  //     this.isUpload = true
	 //  	console.log('ppppppppppppppppppppppppppppppppppppppppppp')
  //     // 如果文件大学小于分片大小，使用普通上传，否则使用分片上传
  //     if (file.size < this.partSize * 1024 * 1024) {
  //       this.commonUpload(file).finally(() => this.isUpload = false)
		// this.isUploading = true;
		// console.log('lllllllllllllllllllllllllllllllllllllllll')
  //     } else {
  //       this.multipartUpload(file).finally(() => this.isUpload = false)
  //     }
  //   },
    async commonUpload(file) {
      let ossClient = this.ossClient
      // if (!ossClient) {
      //   await this.initOSSClient()
      //   ossClient = this.ossClient
      // }
	  await this.initOSSClient()
	  ossClient = this.ossClient
      const suffix = getSuffix(file.name)
      const fileName = `${this.filePath}/${randomString()}${suffix}`
      return ossClient.put(fileName, file, {
        headers: {
          'Content-Type': getContentType(suffix)
        }
      }).then(data => {
        this.$emit('uploadSuccess', {
          name: file.name,
          suffix,
          path: data.url,
          thumbnailPath: data.url + `?x-oss-process=image/resize,w_${this.thumbnailPathWidth}, m_${this.thumbnailPathMode}`
        })
      }).catch(() => {
        this.$message.error(file.name + '上传失败，请重试!')
      })
    },
   async multipartUpload(file) {
		let ossClient = this.ossClient
		// if (!ossClient) {
		//   await this.initOSSClient()
		//   ossClient = this.ossClient
		// }
		await this.initOSSClient()
		ossClient = this.ossClient
      const suffix = getSuffix(file.name)
      const fileName = `${this.filePath}/${randomString()}${suffix}`
      return this.ossClient.multipartUpload(fileName, file, {
        parallel: this.parallel,
        partSize: this.partSize * 1024 * 1024,
        headers: {
          'Content-Type': getContentType(suffix)
        }
      }).then(() => {
        // 生成文件下载地址
        this.$emit('uploadSuccess', {
          status: 'done', // 上传成功
          name: file.name,
          suffix,
          path: this.bucketDomain + fileName,
          thumbnailPath: this.bucketDomain + fileName + `?x-oss-process=image/resize,w_${this.thumbnailPathWidth}, m_${this.thumbnailPathMode}`
        })
      }).catch(() => {
        this.$message.error(file.name + '上传失败，请重试!')
      })
    },
    async initOSSClient() {
      const {
        accessKeyId,
        accessKeySecret,
        securityToken: stsToken,
        bucketName: bucket,
        region,
        filePath,
        bucketDomain
      } = await getOSSToken({ scene: this.scene })
      this.ossClient = new OSS({
        accessKeyId,
        accessKeySecret,
        stsToken,
        bucket,
        region
      })
	  console.log(this.ossClient,'fangfa')
      this.bucketDomain = bucketDomain
      this.filePath = filePath
      if (this.timer) return
      this.timer = setInterval(() => {
        this.seconds++
        if (this.seconds >= 29 * 60 ) {
          this.ossClient = null
          clearInterval(this.timer)
          this.timer = null
          this.seconds = 0
        }
      }, 1000)
    }
  },
  beforeDestroy() {
    clearInterval(this.timer)
    this.timer = null
  }
}
</script>
